String clazzTpl({package}) => """
import 'dart:ui';
import 'dart:async';
import 'screen_util.dart';
import 'font_family_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:$package/mixin/base_widget_mixin.dart';

enum ToastType {
  succ,
  fail,
  warn,
  none,
}

/// Generates Dart code
class Toast {
  static OverlayEntry? _overlayEntry, _overlayEntryLoading;
  static bool _showing = false, _showLoading = false;
  static DateTime? _startedTime, _startedTimeLoading;
  static const int _duration = 2000;
  static String? _msg;

  static void showSucc(String? msg, {double top = 0.0}) async {
    show(msg, type: ToastType.succ);
  }

  static void showFail(String? msg, {double top = 0.0}) async {
    show(msg, type: ToastType.fail);
  }

  static void showWarn(String? msg, {double top = 0.0}) async {
    show(msg, type: ToastType.warn);
  }

  static void show(String? msg, {ToastType type = ToastType.none}) async {
    _msg = msg;
    _startedTime = DateTime.now();
    OverlayState overlayState = globalNavigatorKey.currentState!.overlay!;
    _showing = true;
    if (_overlayEntry == null) {
      _overlayEntry = OverlayEntry(
          builder: (BuildContext context) => _MsgTipsContentWidget(
                showing: _showing,
                msg: _msg ?? '',
                type: type,
                duration: _duration,
              ));
      Future.delayed(Duration.zero, () {
        overlayState.insert(_overlayEntry!);
      });
    } else {
      if (_overlayEntry != null) {
        Future.delayed(Duration.zero, () {
          _showing = false;
          if (_overlayEntry != null) {
            Future.delayed(Duration.zero, () {
              _overlayEntry?.markNeedsBuild();
              _overlayEntry?.remove();
              _overlayEntry = null;
            });
          }
          show(msg, type: type);
        });
      }
    }
    await Future.delayed(const Duration(milliseconds: _duration)); //等待3秒

    if (DateTime.now().difference(_startedTime!).inMilliseconds >= _duration) {
      _showing = false;
      if (_overlayEntry != null) {
        Future.delayed(Duration.zero, () {
          _overlayEntry?.markNeedsBuild();
          _overlayEntry?.remove();
          _overlayEntry = null;
        });
      }
    }
  }

  static void showOld(String? msg,
      {ToastType type = ToastType.none, double top = 0.0}) async {
    _msg = msg;
    _startedTime = DateTime.now();
    OverlayState overlayState = globalNavigatorKey.currentState!.overlay!;
    _showing = true;
    if (_overlayEntry == null) {
      _overlayEntry = OverlayEntry(
          builder: (BuildContext context) => _MsgContentWidget(
                showing: _showing,
                msg: _msg ?? '',
                top: top,
                type: type,
                duration: _duration,
              ));
      Future.delayed(Duration.zero, () {
        overlayState.insert(_overlayEntry!);
      });
    } else {
      if (_overlayEntry != null) {
        Future.delayed(Duration.zero, () {
          _showing = false;
          if (_overlayEntry != null) {
            Future.delayed(Duration.zero, () {
              _overlayEntry?.markNeedsBuild();
              _overlayEntry?.remove();
              _overlayEntry = null;
            });
          }
          show(msg, type: type);
        });
      }
    }
    await Future.delayed(const Duration(milliseconds: _duration)); //等待3秒

    if (DateTime.now().difference(_startedTime!).inMilliseconds >= _duration) {
      _showing = false;
      if (_overlayEntry != null) {
        Future.delayed(Duration.zero, () {
          _overlayEntry?.markNeedsBuild();
          _overlayEntry?.remove();
          _overlayEntry = null;
        });
      }
    }
  }

  static void close() {
    _showing = false;
    if (_overlayEntry != null) {
      Future.delayed(Duration.zero, () {
        _overlayEntry?.markNeedsBuild();
        _overlayEntry?.remove();
        _overlayEntry = null;
      });
    }
  }

  static void closeLoading() {
    _showLoading = false;
    if (_overlayEntryLoading != null) {
      Future.delayed(Duration.zero, () {
        _overlayEntryLoading?.markNeedsBuild();
        _overlayEntryLoading?.remove();
        _overlayEntryLoading = null;
      });
    }
  }

  static void showLoading({duration = 15000}) async {
    OverlayState overlayState = globalNavigatorKey.currentState!.overlay!;
    _startedTimeLoading = DateTime.now();
    _showLoading = true;
    if (_overlayEntryLoading == null) {
      _overlayEntryLoading = OverlayEntry(
          builder: (BuildContext context) => AbsorbPointer(
                absorbing: false,
                child: Container(
                  width: ScreenSizeFit.screenWidth,
                  height: ScreenSizeFit.screenHeight,
                  color: Colors.transparent,
                  alignment: Alignment.center,
                  child: LoadingWidget(showLoading: _showLoading),
                ),
              ));
      Future.delayed(Duration.zero, () {
        overlayState.insert(_overlayEntryLoading!);
      });
    } else {
      if (_overlayEntryLoading != null) {
        Future.delayed(Duration.zero, () {
          _overlayEntryLoading?.markNeedsBuild();
        });
      }
    }
    Future.delayed(Duration(milliseconds: duration), () {
      if (DateTime.now().difference(_startedTimeLoading!).inMilliseconds >=
          duration) {
        _showLoading = false;
        if (_overlayEntryLoading != null) {
          Future.delayed(Duration.zero, () {
            _overlayEntryLoading?.markNeedsBuild();
            _overlayEntryLoading?.remove();
            _overlayEntryLoading = null;
          });
        }
      }
    });
  }
}

class _MsgContentWidget extends StatefulWidget {
  const _MsgContentWidget({
    Key? key,
    required this.showing,
    required this.msg,
    required this.top,
    required this.type,
    required this.duration,
  }) : super(key: key);

  final bool showing;
  final String msg;
  final double top;
  final ToastType type;
  final int duration;

  @override
  State<_MsgContentWidget> createState() => _MsgContentWidgetState();
}

class _MsgContentWidgetState extends State<_MsgContentWidget>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _begin, _end;

  @override
  void initState() {
    _controller = AnimationController(
        duration: Duration(milliseconds: widget.duration), vsync: this);
    _begin = Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(
        parent: _controller,
        curve: const Interval(
          0,
          0.15,
          curve: Curves.ease,
        ),
      ),
    );
    _end = Tween<double>(begin: 1, end: -0.5).animate(
      CurvedAnimation(
        parent: _controller,
        curve: const Interval(
          0.85,
          1,
          curve: Curves.ease,
        ),
      ),
    );
    _controller.forward();
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
        animation: _controller,
        builder: (context, child) {
          double anim = 0;
          if (_controller.value < 0.5) {
            anim = _begin.value;
          } else {
            anim = _end.value;
          }
          return Positioned(
            top: (widget.top > 0 ? widget.top : 170.px) * anim,
            child: Material(
                color: Colors.transparent,
                child: SizedBox(
                  width: ScreenSizeFit.screenWidth,
                  child: Center(
                    child: Container(
                      decoration: ShapeDecoration(
                        shape: const StadiumBorder(),
                        color: const Color(0xFFFF8E36),
                        shadows: [
                          BoxShadow(
                            color: const Color(0xFFFF8E36).withOpacity(0.4),
                            offset: Offset(0, 6.px),
                            blurRadius: 20.px,
                          )
                        ],
                      ),
                      child: Padding(
                        padding: EdgeInsets.symmetric(
                            horizontal: 45.px, vertical: 23.px),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            if (widget.type == ToastType.succ)
//                              Padding(
//                                padding: EdgeInsets.only(right: 14.px),
//                                child: IconFont(IconFontName.TOASTCHENGGONG,
//                                    color: Colors.white, size: 30.px),
//                              ),
                              if (widget.type == ToastType.fail)
//                              Padding(
//                                padding: EdgeInsets.only(right: 14.px),
//                                child: IconFont(IconFontName.TOASTSHIBAI,
//                                    color: Colors.white, size: 30.px),
//                              ),
                                if (widget.type == ToastType.warn)
//                              Padding(
//                                padding: EdgeInsets.only(right: 14.px),
//                                child: IconFont(IconFontName.TOASTJINGSHI,
//                                    color: Colors.white, size: 30.px),
//                              ),
                                  ConstrainedBox(
                                    constraints:
                                        BoxConstraints(maxWidth: 300.px),
                                    child: Text(
                                      widget.msg,
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                      style: TextStyle(
                                        fontSize: 26.sp,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ),
                          ],
                        ),
                      ),
                    ),
                  ),
                )),
          );
        });
  }
}

class _MsgTipsContentWidget extends StatefulWidget {
  const _MsgTipsContentWidget({
    Key? key,
    required this.showing,
    required this.msg,
    required this.type,
    required this.duration,
  }) : super(key: key);

  final bool showing;
  final String msg;
  final ToastType type;
  final int duration;

  @override
  State<_MsgTipsContentWidget> createState() => _MsgTipsContentWidgetState();
}

class _MsgTipsContentWidgetState extends State<_MsgTipsContentWidget>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _begin, _end;
  late bool showing = widget.showing;
  late String msg = widget.msg;
  late ToastType type = widget.type;
  late int duration = widget.duration;

  @override
  void initState() {
    _controller = AnimationController(
        duration: Duration(milliseconds: duration), vsync: this);
    _begin = Tween<double>(begin: -1, end: 0).animate(
      CurvedAnimation(
        parent: _controller,
        curve: const Interval(
          0,
          0.05,
          curve: Curves.ease,
        ),
      ),
    );
    _end = Tween<double>(begin: 0, end: -1).animate(
      CurvedAnimation(
        parent: _controller,
        curve: const Interval(
          0.95,
          1,
          curve: Curves.ease,
        ),
      ),
    );
    _controller.forward();
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
//    IconFontName? iconName;
    Color? color;
    TextStyle style =
        TextStyle(color: Colors.white, fontSize: 28.sp, height: 40 / 28);
    switch (type) {
      case ToastType.succ:
//        iconName = IconFontName.TOASTCHENGGONG;
        color = const Color(0xFF39C27A);
        break;
      case ToastType.fail:
//        iconName = IconFontName.TOASTSHIBAI;
        color = const Color(0xFFFF504D);
        break;
      case ToastType.warn:
//        iconName = IconFontName.TOASTJINGSHI;
        color = const Color(0xFF007AFF);
        break;
      case ToastType.none:
        color = const Color(0xFF39C27A);
        break;
      default:
    }
    Size size;
    MainAxisAlignment mainAxisAlignment;
    TextAlign textAlign;
//    if (iconName != null) {
//      size = textSize(context, msg, style, maxWidth: 750.px - 39.px - 80.px);
//      textAlign = TextAlign.left;
//    } else {
    size = textSize(context, msg, style, maxWidth: 750.px - 80.px);
    textAlign = TextAlign.center;
//    }
    double paddingTop = MediaQuery.of(context).padding.top;
    double height = size.height + 56.px + paddingTop;
    double textWidth = size.width;
    bool oneLine = size.height <= textHeight(context, style);
    int maxLines = oneLine ? 1 : 2;
    if (oneLine) {
      mainAxisAlignment = MainAxisAlignment.center;
    } else {
      mainAxisAlignment = MainAxisAlignment.start;
    }
    return AnimatedBuilder(
        animation: _controller,
        builder: (context, child) {
          double anim = 0;
          if (_controller.value < 0.5) {
            anim = _begin.value;
          } else {
            anim = _end.value;
          }
          return Positioned(
            top: height * anim,
            left: 0,
            right: 0,
            child: Material(
              child: Container(
                color: color,
                height: height,
                padding: EdgeInsets.only(
                    left: 40.px,
                    right: 40.px,
                    top: 26.px + paddingTop,
                    bottom: 30.px),
                child: LayoutBuilder(
                  builder: (context, box) {
                    return Row(
                      mainAxisAlignment: mainAxisAlignment,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
//                        if (iconName != null)
//                          Padding(
//                            padding: EdgeInsets.only(right: 9.px),
//                            child: Transform.translate(
//                              offset: Offset(0, oneLine ? 6.px : -14.px),
//                              child: IconFont(
//                                iconName,
//                                size: 30.px,
//                                color: Colors.white,
//                              ),
//                            ),
//                          ),
                        SizedBox(
                          width: textWidth,
                          child: Text(
                            msg,
                            maxLines: maxLines,
                            textAlign: textAlign,
                            overflow: TextOverflow.ellipsis,
                            style: style,
                          ),
                        ),
                      ],
                    );
                  },
                ),
              ),
            ),
          );
        });
  }
}

class LoadingWidget extends StatelessWidget {
  const LoadingWidget({
    Key? key,
    required bool showLoading,
  })  : _showLoading = showLoading,
        super(key: key);

  final bool _showLoading;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 180.px,
      height: 180.px,
      child: BlurRectWidget(
        color: Colors.transparent,
        child: AnimatedOpacity(
          opacity: _showLoading ? 1.0 : 0.0,
          duration: _showLoading
              ? const Duration(milliseconds: 100)
              : const Duration(milliseconds: 400),
          child: CupertinoActivityIndicator(
            radius: 20.px,
            color: Colors.white,
          ),
        ),
      ),
    );
  }
}

class BlurRectWidget extends StatelessWidget {
  final Widget child;
  final Color? color;
  final double radius;
  final double sigmaX;
  final double sigmaY;

  const BlurRectWidget(
      {required this.child,
      Key? key,
      this.color,
      this.radius = 10,
      this.sigmaX = 20,
      this.sigmaY = 20})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.transparent,
      child: ClipRRect(
        borderRadius: BorderRadius.all(Radius.circular(radius)),
        child: BackdropFilter(
          filter: ImageFilter.blur(
            sigmaX: sigmaX,
            sigmaY: sigmaY,
          ),
          child: Container(
            color: color,
            child: child,
          ),
        ),
      ),
    );
  }
}
""";
